import problem
import problem_agent,math
from search.algorithm import *
from search.astar import *

class ShortestWayProblemState(problem.ProblemState):
    def __init__(self,currentJunctionKey,targetJunctionKey,roadMap):
        self.currentJunctionKey = currentJunctionKey
        self.targetJunctionKey = targetJunctionKey
        self.roadMap = roadMap
        
    def getSuccessors(self):
        successors = {}
        tempJunction = self.roadMap.GetJunction(self.currentJunctionKey)
        for link in tempJunction.links:
            distance = link.distance
            successors.update({ShortestWayProblemAction(distance) : ShortestWayProblemState(link.target,self.targetJunctionKey,self.roadMap)})
        return successors
    
    def isGoal(self):
        return self.currentJunctionKey ==  self.targetJunctionKey
    
    def __cmp__(self, other):
        if id(self.currentJunctionKey) < id(other.currentJunctionKey):
            return -1
        if id(self.currentJunctionKey) > id(other.currentJunctionKey):
            return 1
        return 0
    
    def __hash__(self):
        return (self.currentJunctionKey)
    
    def __str__(self):
        tempJunction = self.roadMap.GetJunction(self.currentJunctionKey)
        return "<State name=%s lat=%s lon=%s>" % (self.currentJunctionKey, tempJunction.lat, tempJunction.lon)
    
    
class ShortestWayProblemAction(problem.ProblemAction):
#    def __init__(self,JunctionKey,cost = 1):
#        self.JunctionKey = JunctionKey
#        problem.ProblemAction.__init__(self, cost)  
#        
    def __cmp__(self, other):
        if id(self) < id(other):
            return -1
        if id(self) > id(other):
            return 1
        return 0
    
    def __hash__(self):
        return id(self)
    
    def __str__(self):
        return "<Action cost %s>" % (self.cost)
    
class ShortestWayProblemAgent (problem_agent.ProblemAgent):
    def solve(self, problem_state, time_limit = problem_agent.NO_LIMIT):
        aStarSearch = AStar(time_limit)
        myHeuristic = ShortestWayHeuristic()
        return aStarSearch.find(problem_state,myHeuristic)
    
class ShortestWayHeuristic(Heuristic):
    def evaluate(self, problem_state):
        distance = problem_state.roadMap.JunctionDistance(problem_state.currentJunctionKey , problem_state.targetJunctionKey)
        
        return (distance)
    